import 'package:app/core/utils/helpers/sp.dart';
import 'package:dio/dio.dart';

import 'config/global.dart';
import 'config/net_cache.dart';
import 'config/request_method.dart';
import 'interceptor/error_interceptor.dart';
import 'interceptor/log_interceptors.dart';

///
class DioManager {
  static final DioManager _dioManager = DioManager._internal();

  factory DioManager() => _dioManager;
  Dio dio;
  static Map<String, CancelToken> _cancelTokenMap;

  ///取消请求
  void _cancelRequest(String tag) {
    if (_cancelTokenMap.containsKey(tag)) {
      if (!_cancelTokenMap[tag].isCancelled) {
        _cancelTokenMap[tag].cancel();
      }
      _cancelTokenMap.remove(tag);
    }
  }

  ///
  DioManager._internal() {
    if (dio == null) {
      _cancelTokenMap = Map();
      BaseOptions options = BaseOptions(
          //通用部分接口
          contentType: Headers.formUrlEncodedContentType,
          connectTimeout: 30000,
          receiveTimeout: 30000);
      dio = Dio(options);

      dio.interceptors.add(CacheInterceptor());
      // dio.interceptors.add(CookieManager(CookieJar()));
      dio.interceptors.add(ErrorInterceptor());

      if (Global.isDebug) {
        dio.interceptors.add(LogsInterceptors());
      }
    }
  }

  ///
  Future request<T>(RequestMethod method, String path,
      {Map<String, dynamic> map}) async {
    _cancelTokenMap[path] = CancelToken();
    if (method == RequestMethod.POST) {
      return await _post(path, map).catchError((err) {
        _cancelRequest(path);
      });
    } else if (method == RequestMethod.GET) {
      return await _get(path, params: map).catchError((err) {
        _cancelRequest(path);
      });
    }
  }

  Future _get(
    String url, {
    Map<String, dynamic> params,
    bool refresh = false,
    bool noCache = !Global.CACHE_ENABLE,
    String cacheKey,
    bool cacheDisk = false,
  }) async {
    Options requestOptions = Options();
    requestOptions = requestOptions.copyWith(extra: {
      "refresh": refresh,
      "noCache": noCache,
      "cacheKey": cacheKey,
      "cacheDisk": cacheDisk,
    });
    Map<String, dynamic> _authorization = _getAuthorizationHeader();
    if (_authorization != null) {
      requestOptions = requestOptions.copyWith(headers: _authorization);
    }
    var response =
        await dio.get(url, queryParameters: params, options: requestOptions);
    return response.data;
  }

  Future _post(String url, Map<String, dynamic> params) async {
    Options requestOptions = Options();
    Map<String, dynamic> _authorization = _getAuthorizationHeader();
    if (_authorization != null) {
      requestOptions = requestOptions.copyWith(headers: _authorization);
    }

    var response = await dio.post(url, data: params, options: requestOptions);
    return response.data;
  }

  // 可以在此保存在本地
  void setHeader(Map<String, dynamic> map) {
    dio.options.headers.addAll(map);
  }

  /// 读取本地配置   可以在此拓展判断期限
  Map<String, dynamic> _getAuthorizationHeader() {
    var headers;
    String accessToken = SpUtil.instance.controller.token;
    if (accessToken != null) {
      headers = {"Authorization": '$accessToken'};
    }
    return headers;
  }

  void init(
      {String baseURL,
      int connectTimeOut,
      int receiveTimeOut,
      List<Interceptor> interceptors}) {
    dio.options = dio.options.copyWith(
        baseUrl: baseURL,
        connectTimeout: connectTimeOut,
        receiveTimeout: receiveTimeOut,
        contentType: 'application/json; charset=utf-8',
        headers: {});
    if (interceptors != null && interceptors.isNotEmpty) {
      dio.interceptors.addAll(interceptors);
    }
  }
}
